home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / pnl004.zip / PNL004.TXT < prev    next >
Text File  |  1990-10-03  |  76KB  |  1,211 lines

  1.  
  2.                                                                
  3.                                                                            
  4.                                                                          
  5.                                   ////////    //    //    //   
  6.                                  //    //    ///   //    //    
  7.                                 //    //    ////  //    //     
  8.                                ////////    // // //    //      
  9.                               //          //  ////    //       
  10.                              //          //   ///    //          
  11.                             //          //    //    ///////    
  12.                                                                            
  13.                                                                            
  14.                                                                        
  15.                                                                       
  16.                                                                       
  17.                                     Pascal NewsLetter         
  18.                                          Issue #4
  19.                                         July, 1990             
  20.                                                                      
  21.                                                                       
  22.                                     Editor: Pete Davis         
  23.                                                                       
  24.                                                                       
  25.                                                                       
  26.                                                                       
  27.                                                                       
  28.                                                                       
  29.                                                                       
  30.                                                                       
  31.                                                                       
  32.                                                                       
  33.                                                                       
  34.                                                                       
  35.                                                                           
  36.                          The Programmer's Forum BBS is the home of
  37.                          PNL. It can be reached in Washington, DC at
  38.                          (202)966-3647. Information is available 
  39.                          through the following locations:        
  40.                                                                    
  41.                          FidoNet:  Pete Davis@1:109/138           
  42.                          Genie:    P.DAVIS5                          
  43.                          BitNet:   HJ647C@GWUVM & UE356C@GWUVM
  44.                          InterNet: HJ647C@GWUVM.GWU.EDU 
  45.                                 or UE356C@GWUVM.GWU.EDU
  46.                                 or Pete.Davis@f138.n109.z1.fidonet.org
  47.  
  48.                                   Table of Contents
  49.                 Introduction ..................................  3 (P.D.)
  50.                 Letters to the Editor .........................  5 (****)
  51.                 Binary Trees For Sorting ......................  7 (R.M.)
  52.                 Putting the Spurs to Pascal ................... 15 (J.R.)
  53.                 For Beginners ................................. 22 (B.G.)
  54.                 Review of TechnoJock's Turbo Toolkit .......... 27 (J.A.)
  55.                 Review of Turbo Pascal-The Complete Reference . 29 (P.D.)
  56.             Key to author names:
  57.             P.D. -> Pete Davis - Senior editor and writer 
  58.             B.G. -> Bob Gowans - Staff writer
  59.             J.R. -> Jan-Erik Rosinowski - Contributing writer
  60.             R.M. -> Robert Mashlan - Contributing writer
  61.             J.A. -> John A. Abele - Contributing writer
  62.                                                                           3
  63.                                      Introduction
  64.                Well, PNL003 finally got off, so now I guess it's about time
  65.           to get started on issue #4.  I was so pleased with PNL003 that  I
  66.           was  worried I might break my arm  patting myself on the back. It
  67.           was a good issue, though, and I was very pleased. I hope issue 4,
  68.           and all the issues to follow for that matter, are just as good or
  69.           better.
  70.                I  received a wonderful letter  the other day  from a reader
  71.           who said  he got a subscription  to the Cobb  Group newsletter on
  72.           Turbo Pascal. He said that he and a friend compared it to PNL and
  73.           said that they  preferred mine.  It's this kind  of support  that
  74.           really makes me want to keep writing this.
  75.                I hope that people will  keep up the contributions.  They've
  76.           been a fantastic  support for me. Without  them, I don't  know if
  77.           I'd be able  to go on  with this. There have  already been a  lot
  78.           sent that I couldn't  have written myself and I think  that makes
  79.           it more interesting for the regular readers.
  80.                Because  of  the  time   consuming  nature  of  writing  the
  81.           NewsLetter, I'm afraid I might be stuck with only putting out one
  82.           issue every  two months or  so. I doubt  it would really  be much
  83.           longer than that. I  am looking into getting some  more permanent
  84.           writers who  I can count on  to write an article  for every issue
  85.           and maybe even pitch in on  the editing. Right now, Bob Gowans is
  86.           the only person who has had the  time to be able to contribute on
  87.           a regular  basis. PNL is still  young, though, and growth  can be
  88.           expected, but it  might slow down a  bit. Since the first  issue,
  89.           the  PNL has grown very quickly,  but things seem to be steadying
  90.           out a bit.
  91.                Well, in this issue  we've got an article on Binary Trees, a
  92.           very powerful data structure, which once understood, can be  very
  93.           easy to implement. I had  already planned on doing an article  on
  94.           Binary Trees,  but got a submission from  a reader on them. Since
  95.           Robert's article covers the  basics of Binary trees, I  decided I
  96.           would  take a  bit more  complex route  and discuss the  AVL tree
  97.           balancing algorithm in a future issue.
  98.                I've  also had a reader, John  Abele, who sent in a terrific
  99.           review of the TechnoJock's Turbo Toolkit. I am doing a review  of
  100.           Turbo Pascal  - The  Complete  Reference by  Stephen K.  O'Brien.
  101.           These will  be only  the start  of reviews that  will be  done on
  102.           books, toolkits, and software related to Pascal. 
  103.                I think the  star of this issue is going  to be the PROFILER
  104.           and accompanying article  that are  in this issue.  I've used  to
  105.           profiler  a bit myself and have found  it very useful. I hope you
  106.           like  it. Originally the article was written in German and thanks
  107.           to the tremendous effort of one of my BBS users, Howard Sanner, I
  108.                                                                           4
  109.           was  able  to  get  the article  translated  to  English.  Howard
  110.           suggested, and  I agreed, that it  was best to leave  the article
  111.           using  some of the expressions that are distinctly German, in the
  112.           article, instead  of trying  to write something  in English  that
  113.           wouldn't  convey the meaning the author was trying to get across.
  114.           I hope this poses no problems.
  115.                All-in-all,  I  think this  issue  came out  very  well, and
  116.           again, let me thank all those who contributed and hopefully I can
  117.           get other readers to contribute also.
  118.                                                                           5
  119.                                 Letters to the Editor
  120.           From  uunet!GWUVM.BITNET!HJ647C
  121.           From: uunet!CUNYVM.CUNY.EDU!CDCKAB%EMUVM1.BITNET (Karl Brendel)
  122.           To:   Pete Davis <HJ647C@GWUVM.UCAR.EDU>
  123.           Date: Fri, 27 Jul 1990 13:04 EDT
  124.           Pete--
  125.           I've just read the second issue of PNL (the first one I've seen).
  126.           Thanks for this work!
  127.                Not  wanting to be critical of article--being critical is so
  128.           much easier  than writing--but Craig Thurber's  references to the
  129.           $L  compiler directive is completely wrong, to the point that you
  130.           really need to issue a correction in your next issue.
  131.                Reference _Turbo  Pascal Reference Guide_ for 5.0 or 5.5, pp
  132.           434-5 and 437-8  in my copy.  {$L filename}  is the "link  object
  133.           file" directive. {$L- or {$L+ are  the "local symbol information"
  134.           directives.  Craig  indicates that  {$L  filename}  is the  local
  135.           symbol  information directive  and that  it  is ignored  if debug
  136.           information  is off ({$D-}) (PNL002, pg 17). He shows an external
  137.           file  linked as {$L+ HELLO.OBJ}.  This will not  work. It appears
  138.           that Craig doesn't understand how to use the link directive.
  139.                It appears to me that neither he nor you tried to compile or
  140.           use  his  code. As  printed,  the  program "Hello"  will  neither
  141.           compile  nor run.  One of the  compile errors  is from  a typo (a
  142.           problem every  publication has), but  the other  is from  Craig's
  143.           misuse of {$L+. I urge you to require your writers to compile and
  144.           run every  single line of code  they send you, and  to repeat the
  145.           compilation and running yourself before publication.
  146.           Best wishes. I'm looking forward to PNL003.
  147.                                           Karl Brendel
  148.                                           Centers for Disease Control
  149.                                           Epidemiology Program Office
  150.                                           Atlanta, GA
  151.           Karl, 
  152.                You  bring up a  valid point. To  be honest, not  all of the
  153.           code  that  goes into  the  articles themselves  has  really been
  154.           checked by me to see if it works. I do read through the  articles
  155.           and try to get an idea of the competency of the writer and see if
  156.           the  ideas are valid. I must admit  that from time to time things
  157.           will  slip  by, but  from  now on,  actual  code  going into  the
  158.           articles will be tested.
  159.                It appears  Craig had made a  small mistake and I  thank you
  160.           for pointing  it out to the  readers. I am afraid  that this will
  161.                                                                           6
  162.           probably happen again, at  some point and hope that in the future
  163.           readers  will respond, as you  have to make  the corrections that
  164.           slip by us here at PNL.
  165.                                               _Pete Davis
  166.                                                Editor
  167.                                                                           7
  168.                                Binary Trees for Sorting
  169.                                   By Robert Mashlan
  170.                A binary  tree  is a  useful  sorting device  in  structured
  171.           programming. It is  a quick and  easy way to  maintain data in  a
  172.           sorted order.
  173.                A  binary tree is composed  of units called  'nodes'.  These
  174.           nodes are linked together  in a special  way to form  a tree.   A
  175.           tree requires the use of pointers, and each node of the tree must
  176.           be  allocated  dynamically. If  you  don't  quite understand  the
  177.           concept of a pointer, don't worry, just read on.
  178.                A pointer is  nothing more  than a variable  that holds  the
  179.           address of another variable. Pointers  are used to access dynamic
  180.           variables, that is, variables  that you can create or  destroy at
  181.           will.   Besides  possessing this flexibility,  you may  hold more
  182.           data with dynamic variables than you could by using global and/or
  183.           local variables.
  184.                In   a   program,   the   construction   of   pointers    is
  185.           straightforward. In  the type  declaration of a  program consider
  186.           the declaration
  187.           Type
  188.              stringptr = ^string;
  189.           or in English, 'Let stringptr denote that all things of this type
  190.           point to things of type string!'.  In the declaration  there is a
  191.           caret  '^'  which simply  means  'pointer  to'.   It  takes  on a
  192.           slightly different meaning when used in the actual code.
  193.           Now we need to declare an instance of a pointer so that it can be
  194.           used:
  195.           Var
  196.              sp : stringptr;
  197.                What we have  done is to declare  an instance of  a variable
  198.           that points to a string.   This variable doesn't take much space;
  199.           pointer in Turbo Pascal it is 4 bytes.
  200.           Now we need to allocate storage for a string on the heap:
  201.           begin
  202.               New(sp);
  203.                What we have done here is  told a set of routines called the
  204.           'Heap Manager'  that we need some  space for a string.   If there
  205.           are 255  bytes in a row,  the Heap manager complies  and sets the
  206.           value  of sp to the address of the  space that it gave us for the
  207.           string.  This space will be  protected from being  given to other
  208.                                                                           8
  209.           requests for space until the space is reclaimed with dispose.
  210.           Now  that we have allocated space for it, we can now use it.  The
  211.           caret '^'  comes into play again as it is needed to dereference a
  212.           pointer.  This means 'refer to the thing I point at'.
  213.               sp^ := 'I am a dynamic string!';
  214.               writeln(sp^);
  215.                Now when we no longer need the string, we can get rid of it,
  216.           possibly reusing the space that  it occupied.  This is  done with
  217.           the dispose function:
  218.               dispose(sp);
  219.            end.
  220.                After using dispose,  the value that sp had is now no longer
  221.           valid.  That  means don't read it, don't change  it, don't use it
  222.           for  anything unless  you reallocate  space for  it with  the new
  223.           procedure.   A pointer with  an invalid value that  is being used
  224.           often causes really  mean bugs.  It may  write to almost anywhere
  225.           in memory, like the next instruction to be executed, the IDE, the
  226.           operating  system,  etc.   The  problem  is  that  these kind  of
  227.           problems may not show up until  much later, such as when you exit
  228.           your program and run another.
  229.                You should also try  not to lose track of  your pointers, or
  230.           you'll get a 'memory leak' that  wastes space that could be  used
  231.           for other purposes.  Whenever a  pointer goes out of scope always
  232.           dispose the space it points at.
  233.                A pointer can also have the special value nil.  This  simply
  234.           means that the pointer points at  nothing.  It can be assigned to
  235.           any pointer.
  236.           Ok, now on to the forest:
  237.           First a graphical demonstration of creating a binary tree:
  238.           Say we have these pieces of data and we want to sort them in
  239.           alphabetical order:
  240.           G, B, A, H, I, E, J, F, C, D
  241.           The first letter G, we will denote as the root of our tree:
  242.                                   G
  243.                                  / \
  244.           The node that G is in points to other nodes, which are
  245.           currently pointing at nothing.
  246.                                                                           9
  247.           Now we add the next letter B.  To add it, we use the algorithm:
  248.           1) Start at the root node
  249.           2) if the node is empty then
  250.                 place the data here
  251.              else
  252.                 if the data is greater than the data at the node then
  253.                    go to the right node
  254.                 else
  255.                    go to the left node
  256.                 go to step 2
  257.           By using this algorithm, we now have
  258.                                  G
  259.                                 / \
  260.                                B
  261.           ( Unused datum: A, H, I, E, J, F, C, D )
  262.           The next step would be:
  263.                                  G
  264.                                 / \
  265.                                B
  266.                               /
  267.                              A
  268.           to
  269.                                   G
  270.                                  / \
  271.                                 B   H
  272.                                /     \
  273.                               A       I
  274.           to
  275.                                   G
  276.                                  / \
  277.                                 B   H
  278.                                / \   \
  279.                               A   E   I
  280.           to
  281.                                   G
  282.                                  / \
  283.                                 B   H
  284.                                / \   \
  285.                               A   E   I
  286.                                        \
  287.                                         J
  288.                                                                          10
  289.           to
  290.                                   G
  291.                                  / \
  292.                                 B   H
  293.                                / \   \
  294.                               A   E   I
  295.                                    \   \
  296.                                     F   J
  297.           to
  298.                                   G
  299.                                  / \
  300.                                 B   H
  301.                                / \   \
  302.                               A   E   I
  303.                                    \   \
  304.                                     F   J
  305.           to
  306.                                   G
  307.                                  / \
  308.                                 B   H
  309.                                / \   \
  310.                               A   E   I
  311.                                  / \   \
  312.                                 C   F   J
  313.           to
  314.                                   G
  315.                                  / \
  316.                                 B   H
  317.                                / \   \
  318.                               A   E   I
  319.                                  / \   \
  320.                                 C   F   J
  321.                                  \
  322.                                   D
  323.                Now we have a strange looking upside down tree that seems to
  324.           have no reason to it.   To use this tree, we must  transverse it.
  325.           This is the name of  a special algorithm that we use  to 'travel'
  326.           through the  tree so  that it comes  out in sorted  order.    The
  327.           traversal algorithm:
  328.           1) start at the root node
  329.           2) do procedure 2
  330.           3) end
  331.           4) if node is not empty then
  332.                 do this procedure with the left node
  333.                 process the data at this node
  334.                 do this procedure for the right node
  335.                                                                          11
  336.                Using  this algorithm  with the  tree we  start at  the root          node. The instructions tell us to go left, so we go to B. Next we
  337.           go to A.   Since there is no left node to A,  we process A, or in
  338.           this case, write it  down.  We now return to B and print it.  The
  339.           instructions say go right, so we end up at  E.  Now we go left to
  340.           the C  node and print it.   Mentally traversing the  rest of this
  341.           tree is left as an exercise to the reader.
  342.                The traversing  algorithm is called recursive,  that is, the
  343.           algorithm calls itself.
  344.                If you have a good mental picture of what a tree is, read on
  345.           for a demonstration of implementing it in Pascal.
  346.           ----------------------
  347.           Program TreeSort;
  348.           Const
  349.              MaxStr = 255;  { The maximum length of strings to be used }
  350.           Type
  351.              Str = string[MaxStr];  { Our string type to be used }
  352.           { We now declare a node record and pointer type: }
  353.              nodeptr = ^node;
  354.              node = record
  355.                 data : str;
  356.                 left, right : nodeptr;
  357.              end;  { record }
  358.           {  The node record  type has three fields.  The first field data,
  359.           is used to  store a string, the things we are  to sort.  The left
  360.           and right fields  contain pointers  to other nodes.   When  these
  361.           nodes aren't pointing at  other nodes, they will be  assigned the
  362.           value nil.   }
  363.           { Next we must have a root to our tree: }
  364.           Var
  365.              root : nodeptr;
  366.           { Root is not actually the root, but a pointer that will point to
  367.             the root node of our tree. }
  368.              InData : str;
  369.           { This variable will be used by the main block of this program }
  370.                                                                          12
  371.           Function NewNode( var newdata : str ) : nodeptr;
  372.           { The purpose of this function is to allocate and and initialize
  373.             space for a node.  The newdata parameter is the string that
  374.             will be placed into the Node's data field.  newdata is passed
  375.             by reference to reduce stack usage. }
  376.           var
  377.             result : nodeptr; { the value to be returned }
  378.           begin
  379.              New(result);  { allocate space for the new node }
  380.              with result^ do
  381.              begin
  382.                 left := nil;  { set these pointers to point at nothing }
  383.                 right := nil;
  384.                 data := newdata; { store the data in the node }
  385.              end;  {with}
  386.              NewNode := result;
  387.           end; {Function NewNode}
  388.           Procedure Add( var newdata : str );
  389.           {   This procedure is  an implementation of  the 'word' algorithm
  390.           used
  391.              to add data to the graphical tree.  The string that is passed
  392.              as a parameter will be stored in the tree.  }
  393.           var
  394.              chase : nodeptr;  { this pointer is used for }
  395.                                { moving through the tree  }
  396.              done : boolean;   { the done flag }
  397.              Function Compare( var a,b : str ) : boolean;
  398.              { This nested function tells the outer procedure the order
  399.                that the data is to be sorted. It is to return TRUE is a is
  400.                to go to the left of b.  In this case we are comparing
  401.                strings in alphabetical order with no regard to case  }
  402.              var
  403.                 i, limit : integer;
  404.              begin
  405.                if length(a) < length(b) then  { limit is to be the maximum}
  406.                   limit := length(a)          { number of times to loop,  }
  407.                else                           { In this case, the length  }
  408.                   limit := length(b);         { of the shortest string.   }
  409.                 i := 1;
  410.                 while ( i <= limit ) and ( Upcase(a[i]) = UpCase(b[i]) ) do
  411.                    i := succ(i);  { Increment i }
  412.                 { at this point either a mismatch occured or the strings   
  413.                                                                          13
  414.                   Matched up to the length of the shortest string         }
  415.                 if UpCase(a[i])=UpCase(b[i]) then
  416.                    Compare := length(a) > length(b)
  417.                       { longer strings go after shorter ones }
  418.                 else
  419.                    Compare := UpCase(a[i]) > UpCase(b[i]);
  420.              end; {Function Add.Compare}
  421.           begin
  422.              if root = nil then
  423.                 root := NewNode(newdata)  { gotta start somewhere }
  424.              else
  425.              begin
  426.                 done := false;
  427.                 chase := root;  { start at root }
  428.                 repeat
  429.                    with chase^ do
  430.                    begin
  431.                       if Compare( data, NewData ) then {go to the left}
  432.                          if left = nil then
  433.                          begin                         {put the data here}
  434.                             left := NewNode(newdata);
  435.                             done := true;
  436.                          end
  437.                          else
  438.                             chase := left    { move on to the left node }
  439.                       else                      { go to the right }
  440.                          if right = nil then
  441.                          begin                      { put the data here }
  442.                             right := NewNode(newdata);
  443.                             done := true;
  444.                          end
  445.                          else
  446.                             chase := right;   { move on to the right node }
  447.                      end; {with}
  448.                 until done;
  449.              end; {else root=nil}
  450.           end; {Procedure Add}
  451.           Procedure Transverse( np : nodeptr );
  452.           { This is the transversal procedure to the tree.  It calls the
  453.             nested function Process in sorted order. Note that this
  454.             procedure is recursive.  }
  455.              Procedure Process;
  456.              begin
  457.                 writeln(Output, np^.data);{write data to standard output}
  458.              end; {Procedure Transverse.Process}
  459.           begin
  460.                                                                          14
  461.              if np <> nil then
  462.                 with np^ do
  463.                 begin
  464.                    Transverse(left);
  465.                    Process;
  466.                    Transverse(right);
  467.                 end; {with}
  468.           end; {Procedure Transverse}
  469.           {Pretty short, huh?}
  470.           begin {Program TreeSort}
  471.           { This program is a filter, that is, it takes input from
  472.             standard input, sorts it, and send it to standard output.
  473.             It works like the sort filter you get with MS-DOS            }
  474.              root := nil;  { initialize Root }
  475.              while( not eof(Input) ) do   { read all the input datum }
  476.              begin
  477.                 readln(Input,InData);
  478.                 Add(InData);
  479.              end;
  480.              Transverse(root);
  481.              { transverse the tree and write out the datum }
  482.           end. {Program TreeSort}
  483.           ----------------------
  484.           To use this program, create an ascii text file of strings to
  485.           sort.  Type in the command:
  486.           >treesort < data.dat
  487.           and the sorted output will be displayed.
  488.                Binary trees  are useful for many  sorting applications, and
  489.           are fairly quick.  There are a few disadvantages to binary trees,
  490.           namely the recursive nature  of the transversal algorithm.   In a
  491.           case where the incoming  data is nearly or  already sorted.   The
  492.           tree  will appear  to look  like a  linked list,  or a  very long
  493.           chain.   This will cause the transversal algorithm to call itself
  494.           many times and possibly cause a stack overflow error.
  495.             That's  it.  If you have in  questions or comments, you may ask
  496.           them  in the  FidoNet International  Pascal Echo  or via  FidoNet
  497.           NetMail to Robert Mashlan @ 1:147/34.33
  498.                                                                          15
  499.                              PUTTING THE SPURS TO PASCAL
  500.                                 by Jan-Erik Rosinowski
  501.                Does it un-nerve you when, with increasing development time,
  502.           your program runs progressively  slower? Editors that cannot keep
  503.           up with the cursor? Databases that  seem to be stored on cassette
  504.           tape? Though the complexity of the problem can cause  bewildering
  505.           frustration,  it is constructive to use a profiler at this point.
  506.           It  will expose  the time-consuming  procedures, so  that nothing
  507.           will stand in the  way of subsequent significant  optimization of
  508.           the program. Such a profiler for Turbo Pascal v. 4 and 5 programs
  509.           is described below.
  510.                There  are  two  approaches  to  program  optimization,  the
  511.           theoretical  and  the  practical.   They  will  both  be  briefly
  512.           sketched.
  513.                      PROGRAM OPTIMIZATION IN THEORY AND PRACTICE
  514.                          
  515.                The  theorist  uses the  following  method:  using a  simply
  516.           canonical approach,  he  searches  for  the  theoretically  lower
  517.           limits of the best algorithm. The time to formulate and verify an
  518.           algorithm  is  limited  only  by  the  author's  maximum  writing
  519.           speed--at the latest,  after a midnight  snack of pizza he  is in
  520.           the  know. For him, the implementation of the algorithm is almost
  521.           secondary: This would require  him to write a small  program, and
  522.           in such a manner could many free hours and years pass!
  523.                In  contrast,  the  graceless  practitioner: He  writes  his
  524.           database program  using a BASIC interpreter.  Before thinking two
  525.           minutes  about the  program, he  has written  100 lines.  After a
  526.           hundred  test runs  that help  him in  the "verification"  of his
  527.           program,  he  has  a  bug  free  version.  He  often  thinks  the
  528.           following: The program's done.  Only he can no longer  coordinate
  529.           the long coffee  break his  computer's run time  has forced  upon
  530.           him.  After a compiler doesn't  help him, he  decides to re-write
  531.           the program in assembler. For quick  access to his data, he  once
  532.           again uses a linear, sequential search.
  533.                               AND HOW ONE DOES IT RIGHT
  534.                Though  both examples  were  exaggerated, it  is clear  that
  535.           neither approach  is workable.  Clever optimization of  a program
  536.           comes after a careful analysis of the problem and costs. Then one
  537.           must next analyze the kernel functions of the planned program. In
  538.           a database  program, these  would be,  for example, functions  to
  539.           insert,  update, delete,  search, and  index data  records. Along
  540.           with the expected quantity and format of data and operations, one
  541.                                                                          16
  542.           also selects  appropriate data structures. Thus  one chooses here
  543.           suitable algorithms, for  example, linear searching,  B-trees, or
  544.           hashing. An  estimation of  the expected overall  complexity, the
  545.           provision of resources (time, money, tools), and taste/experience
  546.           will quickly determine the high or low-level programming language
  547.           to be used.
  548.                After  solving the  general complexity  of the  problem, one
  549.           should, in  the first, analytical phase, in no case underestimate
  550.           the time taken up by operating system functions. In many programs
  551.           they claim a large part of the total run time.  Bypassing DOS and
  552.           BIOS  calls will definitely yield a copious increase in speed, at
  553.           the cost of  many gray hairs when porting the  program to another
  554.           system. Routines with extreme requirements, for example, a screen
  555.           handling package for a text program, will need to be purchased.
  556.                                       AND THEN!
  557.                After choosing appropriate  algorithms, data structures, and
  558.           programming  languages,  places  ripe  for  optimization  can  be
  559.           quickly identified. There  are, of course,  many sloppily-written
  560.           small routines that  are called unexpectedly often.  If these are
  561.           optimized first, relatively small  optimizations will yield a big
  562.           improvement  in  run  time.  Routines  should  be  re-written  in
  563.           assembler  or,  for  example,  a  bubble  sort  replaced  with  a
  564.           quicksort.
  565.                The amount of improvement to be gained from using a profiler
  566.           is inversely proportional to  the amount of thought put  into the
  567.           original  design. In other words,  the greater effort  put into a
  568.           statement, analysis, and evaluation of the problem, the fewer the
  569.           opportunities  for   improvement.  The  true  art   of  efficient
  570.           programming thus  lies in  appropriate decisions in  the analysis
  571.           and coding phase.
  572.                                        PRACTICE
  573.                With the profiler's help,  you can quickly do away  with the
  574.           worst time wasters in a Turbo Pascal program. The program package
  575.           consists of a preprocessor (PROFILER.PAS) as well as the analysis
  576.           unit, PROFILE.PAS. The  work of  the preprocessor is  to imbed  a
  577.           call  to "PBegin"  and PEnd"  at the  beginning and  end of  each
  578.           function, respectively. (See listings 4 and  5.) When the program
  579.           runs, these procedures capture timing statistics. Both the format
  580.           and  use  of  upper  and  lower  case  in  the  source  code  are
  581.           unimportant. Include files and source code of available units are
  582.           both  processed. In  addition, the  Pascal ugliness  of "Record,"
  583.           "Case," and "End" (in  contrast to Modula-2 or single  logic only
  584.                                                                          17
  585.           "End") is digested without complaint.
  586.                The  programs were  developed under  Turbo Pascal  5.0. Only
  587.           changes to a few CONST declarations and case selectors are needed
  588.           to  adapt  it  to  the  previous  version.  The  assembler  part,
  589.           PROTIMER.ASM, was assembled with MASM.
  590.                                       WILLY GO!
  591.                The preprocessor  "PROFILER" runs only from  the DOS command
  592.           line. The first  parameter expected  is that of  the name of  the
  593.           module to be analyzed. This  can be either one unit or  the whole
  594.           program. Modules linked  in with "uses" or include directives are
  595.           each processed. If  one wants to  omit a module  (e.g., one  that
  596.           exclusively  reads the keyboard via  the BIOS), one  can name the
  597.           file to be excluded after the /X: option. Names without extension
  598.           are interpreted as ".PAS,"  and this applies to all  source files
  599.           (thus  units  to be  excluded with  "/X:  XYZ.TPU" will  cause an
  600.           error).
  601.                In order not to inflate the profiler's size, it assumes that
  602.           the  program to  be processed  has no  syntax errors.  This isn't
  603.           really a restriction, since  the profiler is intended to  be used
  604.           to  put the finishing touches  on the program.  The profiler will
  605.           also not be  of help to  people who, as already  mentioned above,
  606.           plan  their  programs  in the  coding  phase.  The  module to  be
  607.           profiled  must   always  have   either  a  "Program"   or  "Unit"
  608.           identifier.
  609.                                    THE BIG RENAMING
  610.                So that one  can't work  with source code  the profiler  has
  611.           processed  (the  time checking  calls will  not  be found  in the
  612.           finished program),  the files to  be processed are  renamed. Thus
  613.           the first and last letters of the extension are exchanged (".PAS"
  614.           becomes ".SAP"). This can nevertheless lead to problems  should a
  615.           program be run through the profiler  again, as well as with files
  616.           like,  for example, "INCLUDE.010." The  latter must be renamed to
  617.           something reasonable. The PAS-SAP  collision is best avoided with
  618.           a  batch file that will  copy the identically  named ".SAP" files
  619.           over the ".PAS" files. The latter may then be deleted.
  620.                           INTERPRETING THE RUN TIME PROFILE
  621.                After one  has compiled  the profiler-processed  program and
  622.           tested it adequately, the unit PROFILE will generate the run time
  623.           analysis  [PROGRAM/UNIT  NAME].PRF  from  the  file [PROGRAM/UNIT
  624.                                                                          18
  625.           NAME].PR$  produced by the profiler.  In the first  column is the
  626.           procedure name,  in the second  the number  of calls, and  in the
  627.           third column the  run time  in milliseconds. In  contrast to  the
  628.           notion of run time in  reference (1), here it means only  the run
  629.           time of  the procedure itself.  It does not  include that of  the
  630.           subprocedures it  calls. This  considerably simplifies  usage, so
  631.           that  one can  directly see  the true  time a  procedure consumes
  632.           (figure  1). By means of the DOS  SORT program one can generate a
  633.           list by run time, so that one can immediately find the slow parts
  634.           of a large program.
  635.                The  definition of run time in reference (1), in contrast to
  636.           that given here,  always shows  100% for the  main program's  run
  637.           time, which is true in few cases.
  638.                A marginal note: Anyone who  tests the entire program  being
  639.           analyzed  with  the profiler  and  gets  unexpected results  must
  640.           remember that the  time the  profiling unit itself  takes can  be
  641.           compensated for by  setting the variable "adjusttimer"  to a more
  642.           precise value. The true run time of the program is small compared
  643.           to that of the stopped.
  644.                Should  one wish  to test  the program  isolated  in diverse
  645.           situations, one can delete  the uninteresting procedures from the
  646.           ".PR$" file with a  text editor. (Delete whole lines.)  This will
  647.           greatly  reduce the  confusion of paper,  since the  profile unit
  648.           will  only emit a run  time profile for  procedures in the ".PR$"
  649.           file.
  650.                Should  the program  terminate before the  "End." statement,
  651.           there will nevertheless be a run time analysis. In  this case the
  652.           profiler will issue a corresponding warning. This can happen, for
  653.           example, if the  profiler is  used to analyze  itself, since  the
  654.           main  program terminates with a  halt statement. The  run time of
  655.           the "open" procedure will be approximate.
  656.                One  small  piece  of  bad  news:  External  procedures  (in
  657.           assembler or C, for example) cannot be directly analyzed. If this
  658.           is desired, one  must enclose  them in an  outer procedure.  This
  659.           presupposes changes to the external procedures (public names); an
  660.           extension of  the profiler  in this  regard would be  excessively
  661.           complex.
  662.                                       INTERNALS
  663.           The  profiler  consists  of   two  kernel  procedures:  one,  the
  664.           recursive function  "prep_module" that  inserts the calls  to the
  665.           profiler. It  is recursive,  since it  calls itself in  analyzing
  666.           uses  and  include modules.  This  serves  to simplify  the  file
  667.           management,  since thus Turbo  Pascal gets  stuck with  the dirty
  668.                                                                          19
  669.           work.  The  second  important  procedure,  "getsymbol,"  supplies
  670.           "prep_module" with  tokens and handles include  modules. That the
  671.           rest of allocated storage isn't released should not  trouble you;
  672.           DOS also  takes no notice of it,  since the management is handled
  673.           internally by Turbo Pascal.
  674.                The  most   important  function  of  the   unit  PROFILE  is
  675.           "readtimer."  It makes  possible accurate  timing at  microsecond
  676.           intervals; it thus has  substantially greater resolution than the
  677.           BIOS  or DOS timers.  In spite of  what the manuals  say, the DOS
  678.           timer cannot resolve time finer than  five milliseconds. The more
  679.           precise  results  of  the  "readtimer"  procedure  are  also  not
  680.           surprising,  when we consider the fact that the BIOS timer, which
  681.           is  also used by  DOS, is incremented whenever  the timer used in
  682.           the  "readtimer" procedure counts down to zero. Timer zero of the
  683.           8253 chip acts as time keeper. It is critical in this  connection
  684.           to coordinate with the 8259 interrupt controller; under the worst
  685.           circumstances it can  falsify the measurements "catastrophically"
  686.           (by five milliseconds).  This can  happen if the  timer has  been
  687.           latched  and  an  interrupt is  triggered  between  the time  the
  688.           counter value  is stored and  the interrupt  request register  is
  689.           read.  An extremely low counter value indicates that request flag
  690.           has been set. Since this is nevertheless influenced by the timer-
  691.           independent CPU  frequency, an adjustment of  the constant "corr"
  692.           in PROTIMER.ASM is needed. Also,  the DRAM refresh and  installed
  693.           cache programs (DOS buffers,  FASTOPEN, VCache, etc.) falsify the
  694.           measurement not inconsiderably. For these reasons it is important
  695.           to  keep the timer resolution  under 1/100000 seconds  and not to
  696.           put the unit  PROFILE into  an overlay. The  constant "fracs"  in
  697.           PROFILE.PAS determines the number of decimal digits to  which the
  698.           run time in milliseconds will be displayed.
  699.                The unit  PROFILE will  normally be  the first  unit entered
  700.           once the program is  started and the last left (via an Exitproc).
  701.           The counter  is installed,  and  the correction  value needed  to
  702.           account for calls to "PBegin" and "Pend" calculated, via calls to
  703.           the initialization blocks. The local stack as well as the storage
  704.           space  "procstore"  are statically  declared,  and  the constants
  705.           "stacksize" and  "maxprocedures" must be adjusted. Dynamic memory
  706.           allocation  in the profiler might cause errors, since the program
  707.           to  be analyzed  could  also  manage  its  storage  by  means  of
  708.           MARK/RELEASE or also DISPOSE.
  709.                Listing  5 is  presented as an  example of  capturing timing
  710.           information.  Time measurement  begins  with PBegin  (1).   Since
  711.           nothing is on the stack yet, PBegin stores only the number of the
  712.           active  procedure (1) as  well as  the system  time. The  call to
  713.           PBegin (2) in the procedure "a" causes the time used in procedure
  714.           1 (stored  time-elapsed time-  correction value) to  be saved  in
  715.           "procedure[1].time." Again the number of the active procedure (2)
  716.           and the  system time are pushed  on the stack. PEnd  performs the
  717.           analog:  it closes  off the  active procedure  and then  pops its
  718.                                                                          20
  719.           record  off the stack. Since the system  time is once again read,
  720.           the second  call to PEnd can  determine the run time  of the main
  721.           program correctly.
  722.                                   LIMITATIONS OF USE
  723.                Use  of the profiler can  lead to problems  in the following
  724.           circumstances:
  725.           1. As mentioned above, extra steps are needed
  726.              to analyze procedures written in other languages.
  727.              They must be given different public names so that
  728.              one can write enclosing procedures with their
  729.              original names. If only a few modules are involved,
  730.              it may be quicker to change the names in the Pascal
  731.              source.
  732.           2. Programs or PCs that themselves make use of
  733.              timer zero can cause minor irritations and
  734.              influence the unit PROFILE, respectively. In this
  735.              case, the procedure READTIMER (PROTIMER.ASM) must
  736.              be changed.
  737.           3. The run time analysis is only procedural.
  738.              The time taken by DOS and run time library calls
  739.              must also be accounted for. One would be well
  740.              advised, for example, to redefine the file
  741.              functions in their own unit. "READ" and "WRITE"
  742.              statements unfortunately often evade this method.
  743.              In individual, truly critical cases, one can extend
  744.              the ".PR$" file with a pseudo-procedure after the
  745.              last line. It will then carry all the PBegin and
  746.              PEnd calls associated with the "READ" and "WRITE"
  747.              statements.
  748.           4. Time critical procedures, as, for example,
  749.              a serial port handler, will take longer to run, and
  750.              thus the profiler may interfere with their
  751.              operation. For this reason, interrupt procedures
  752.              are automatically excluded from analysis. One must
  753.              either delete the PBegin and PEnd statements from
  754.              time critical procedures or put them in units or
  755.              include modules that are excluded with the /X
  756.              directive from analysis.
  757.           5. "Inline" procedures cannot be analyzed with
  758.              any tricks. This corresponds to their character.
  759.              The shortest machine programs execute in a fraction
  760.              of a microsecond. Anyone who would like to analyze
  761.              such a time critical section should perhaps
  762.                                                                          21
  763.              consider coding it completely in assembler.
  764.                With these hurdles  crossed, nothing  stands in  the way  of
  765.           analyzing your critical source  code. One should, however, always
  766.           put  readability and correctness  of a program  before its speed,
  767.           otherwise one can program the same as in C or BASIC.
  768.    
  769.                          References
  770.                          
  771.                          1. Profilgewinn, c't 5/89.
  772.                          2. Interrupts auf Reihe, 5/86.
  773.                          3. Die PC-Referenz 
  774.    
  775.  
  776.                           Figures
  777.                          1. PROTEST.PRF: This is the result of the analysis
  778.                             of PROTEST with the unit PROFILE.
  779.  
  780.                          Listings
  781.                          
  782.                          1. PROFILER.PAS: This program links calls into
  783.                             Turbo Pascal 4/5 compatible source code that
  784.                              make possible an analysis accurate to the
  785.                              microsecond.
  786.                          2. PROFILE.PAS: This unit measures the procedure
  787.                             run times and generates a run time profile from
  788.                             them.
  789.                          3. PROTIMER.ASM: This procedure can read the timer
  790.                             with microsecond precision.
  791.                          4. PROTEST.SAP: The program to be analyzed
  792.                             appeared thus before the application of the
  793.                             profiler.
  794.                          5. PROTEST.PAS: The profiler has here performed
  795.                             all of its work.
  796.                                                                          22
  797.                                     For Beginners
  798.                                     By Bob Gowans
  799.                In  the last issue of PNL the beginners column discussed the
  800.           use of the Pascal assignment operator ( := ) to  assign values to
  801.           variables.  We  were  concerned  mainly with  operations  on  the
  802.           variable data type integer,  a simple Pascal data type,  and were
  803.           made aware of other  Pascal data types such as char,  Boolean and
  804.           real. In this  issue we  will further increase  our knowledge  of
  805.           variable   operations   by  designing   a   simple   program  and
  806.           implementing our design  as a  Pascal program.  In particular  we
  807.           will  be  paying close  attention  to  correct initialization  of
  808.           variables and input and output.
  809.                Later you will be  presented with a simple problem  and from
  810.           this we will devise a design to solve this problem but first lets
  811.           discuss the technique by which we may solve the problem. First we
  812.           must make sure that  we fully understand the problem.  How?... By
  813.           asking relevant questions so that we are  made fully aware of all
  814.           the details  of the problem.  For example,  if we  were asked  to
  815.           update  a catalogue  of books  we  might ask  How many  books are
  816.           there?  Are they to  be ordered? How  are they to  be ordered, by
  817.           title or by author? You can probably think of many more questions
  818.           to  ask  until  you  are  fully  satisfied  that  you  thoroughly
  819.           understand the problem.
  820.                Next we would  start to  devise a solution  keeping in  mind
  821.           that our ultimate aim is to implement the solution to the problem
  822.           by  making use of a computer. Devising an efficient solution when
  823.           using  a computer  is  something that  comes  about as  you  gain
  824.           experience of your computer system's capabilities, its advantages
  825.           and disadvantages.
  826.                One  of the best methods of problem  solving is by a process
  827.           known as  TOP-DOWN DESIGN. This involves  simplifying the problem
  828.           into a series  of broad terms and then adding  more detail as you
  829.           look at each  term. For example,  the solution to the  problem of
  830.           how to update a bank account is given as follows:
  831.                (a) Give a broad outline
  832.                    1. read in transactions
  833.                    2. bring the accounts up to date
  834.                    3. print out a list of transactions
  835.                (b) Start to refine the broad outline
  836.                    1.1 read in credits
  837.                    1.2 read in debits
  838.                    2.1 calculate the total credits
  839.                    2.2 calculate the total debits
  840.                    2.3 calculate the new balance
  841.                    3.1 print out credits
  842.                    3.2 print out debits
  843.                                                                          23
  844.                    3.3 print out new balance
  845.                Each  step would then  be further refined until  we are at a
  846.           position to implement the solution.
  847.                Implementing the  solution would result in  the construction
  848.           of a Pascal program from our  refined design. When the program is
  849.           entered  into the  computer  and successfully  executed then  the
  850.           associated  problem  is  solved. Whenever  a  solution  is  to be
  851.           implemented there are three important stages to consider :
  852.                1) Data input or reading in information to the program.
  853.                2) Processing instructions - the main body of the
  854.                  program.
  855.                3) Results or output. For example, to the printer or
  856.                   screen or some other output device.
  857.                After  having completed  the implementation  of  your design
  858.           successfully,  always  go  back  over what  you  have  done,  ask
  859.           yourself if you managed to solve the problem to your satisfaction
  860.           and  does the  solution  work for  all  cases that  could  arise?
  861.           Finally it  is vital that you  make a written record  of what you
  862.           have  done. Say  for example  several months  later, you  want to
  863.           amend  the  program. If  you  have  clear, concise  documentation
  864.           covering all aspects of your design and solution then the process
  865.           of amendment should be made much less painful.
  866.                Now  lets take a simple problem and using the above, process
  867.           solutions ready for implementation in Pascal.
  868.           Problem 1 : We  are going back to  the bank again. This  time the
  869.           bank manager has asked  us to devise  a program that will  assist
  870.           his customers. He  wants an interactive program  that will prompt
  871.           the user for the  balance in his deposit  account and then  print
  872.           out, to the computer screen, the new balance with interest at the
  873.           end of the first interest period.
  874.           First lets ask some questions :
  875.           1) What is the current rate of interest?
  876.           2) Over what period is the interest calculated?
  877.           3) How is the new balance to be calculated?
  878.           4) What will happen if there is a withdrawal from the account?
  879.                Ask  as many  questions  as you  like  until you  are  fully
  880.           satisfied  that you  understand the  problem. For the  purpose of
  881.           this problem  the bank  manager supplies  you with  the following
  882.           answers :
  883.           1) Interest is paid annually at 13%
  884.           2) The period of interest is quarterly ie 3 months
  885.           3) The new balance is the current deposit plus the accumulated
  886.             interest.
  887.                                                                          24
  888.           4) The account is new and no withdrawals are allowed
  889.                We are now in a position to construct a broad design of the
  890.           intended program.
  891.                1. set values of variables ( or initialize variables )
  892.                2. calculate the new balance at the end of the quarter
  893.                3. write out the result
  894.                The broad  outline is  easy and understandable  and although
  895.           this is a  much simplified  case the same  principles apply  when
  896.           dealing with more complex design. Let us continue by refining the
  897.           broad outline to a more specific list of instructions. 
  898.                1.1 initialize interest rate
  899.                1.2 initialize interest period
  900.                1.3 initialize deposit
  901.                2.1 calculate interest
  902.                2.2 set balance to deposit + interest
  903.                3.1 write out 'New balance is ', balance
  904.                The design is now at  a stage where it could  be implemented
  905.           as a Pascal program,  however there is nothing  to stop you  from
  906.           further  refining the design if  you think it  necessary. At this
  907.           point it would be beneficial to stop and  reflect over our design
  908.           for a moment  or two. In  our design there  are three  statements
  909.           asking  us to  initialize  certain  data,  if  a  data  table  is
  910.           constructed we can  make clear  the data structures  and what  we
  911.           intend to do with them.
  912.           Identifier     Description                  Type
  913.           ==========     ===========                  ====
  914.           deposit        amount of money in account   real variable
  915.           rate           interest rate per year       real variable
  916.           interest       calculated interest          real variable
  917.           quarter        period over which the
  918.                          interest is calculated       real variable
  919.           balance        total money in the account
  920.                          after first quarter          real variable
  921.                The design has introduced a new data  type REAL. A real data
  922.           type is  defined as 'positive  and negative numbers  that include
  923.           decimal points'. Our real variables must be initialized, or given
  924.           a starting value before they  can appear in an expression  in the
  925.           program.  It is  true  to  say  that  many  Pascal  systems  will
  926.           automatically  initialize variables  to zero,  however it  is not
  927.           good programming practice to presume this  and  it is much better
  928.           if you ensure that all variables used in the program are properly
  929.           initialized.
  930.                Using  the data table we can now write the declarations part
  931.           of the program ( the part where all the variables are declared ).
  932.                                                                          25
  933.           var
  934.              deposit  : real;
  935.              rate     : real;
  936.              quarter  : real;
  937.              interest : real;
  938.              balance  : real;
  939.           Note this could also be written as
  940.           var
  941.              deposit,rate,quarter,interest,balance : real;
  942.           Initializing the variables in Pascal is as follows, using the
  943.           statements from lines 1.1, 1.2 and 1.3 of our design
  944.           rate := 0.13; { 13% as a decimal fraction }
  945.           quarter := 0.25; { 1/4 of a year expressed as a decimal }
  946.           readln(deposit);
  947.                The  first  two  lines make  use  of  the Pascal  assignment
  948.           operator ( := ) which we discussed in the last  issue of PNL. The
  949.           readln statement  is new to us and merits a brief discussion. The
  950.           use of the  readln statement  results in assigning  a value to  a
  951.           variable  from an external source ie from outside the program. As
  952.           our program specified an interactive design we expect the user to
  953.           input some information, a passing of information must take  place
  954.           between the user and  the computer. The program will  temporarily
  955.           halt when it encounters the readln statement, expecting some data
  956.           to be input.  It is vital  that interactive programs  communicate
  957.           while they run  so that the user will know when he is required to
  958.           input the data. The way to do this is to use a program prompt. It
  959.           is  also important that interactive  prompts ask make clear their
  960.           purpose. Lets add  an interactive prompt to  our program ensuring
  961.           it comes before the readln statement.
  962.           write('Please enter your deposit here > ');
  963.           Steps 2.1 and 2.2 of our design are fairly straight forward
  964.           and are implemented as follows :
  965.           interest := deposit*rate*quarter;
  966.           balance  := deposit + interest;
  967.           Finally step1 requires the output to the screen for the
  968.           information of the user.
  969.           writeln('The new balance is ',balance:10:2);
  970.                The writeln statement  informs the user of his  balance plus
  971.           interest and provides a  neat format. The :10 after  the variable
  972.           balance allows a field width of  10 characters for the output and
  973.           the :2 ensures the  output is rounded to two decimal  places. Try
  974.                                                                          26
  975.           the program without these output controls and note the results.
  976.           The whole program can now be put together;
  977.           program new_balance;
  978.           { calculates balance on deposit at a rate of 13 % over 3
  979.           months }
  980.           var
  981.              deposit : real; { entered by user }
  982.              rate    : real; { current rate of interest}
  983.              quarter : real;  { a period of three months }
  984.              interest : real; { calculated interest on deposit }
  985.              balance  : real;  { the new balance }
  986.           begin
  987.              rate := 0.13;
  988.              quarter := 0.25;
  989.              write('Please enter your deposit here > ');
  990.              readln(deposit);
  991.              interest := deposit*rate*quarter;
  992.              balance := deposit + interest;
  993.              writeln('New balance is ',balance:10:2)
  994.           end.
  995.                In  conclusion top down design  is a method  for designing a
  996.           solution  to  a problem  that  is going  to  be implemented  on a
  997.           computer.  If you look at  the design, it  is understandable to a
  998.           non  programming  person as  it conveys  a  broad outline  of the
  999.           problem. With further levels  of refinement and a data  table you
  1000.           are ready to implement your design. Show your final coded program
  1001.           to the  same non programming  person and the chances  are that he
  1002.           will have no idea  what it is  about. By designing your  programs
  1003.           before coding them, you will have a much more clear understanding
  1004.           of exactly what your  program does and will find that coding soon
  1005.           becomes routine and effortless.
  1006.           Error  : In PNL # 3 the  following line should be inserted in the
  1007.           program add_up
  1008.           after male := 100; :- total := male + female;
  1009.           I hope that this  did not distract from the understanding  of the
  1010.           program.
  1011.                                                                          27
  1012.                               TechnoJock's Turbo Toolkit
  1013.                                        A Review
  1014.                                    by John A. Abele
  1015.                Those of us who are serious/professional programmers need to
  1016.           know about  those rare  individuals who have  become programmer's
  1017.           programmers. These  folks write the toolkits  and other utilities
  1018.           that save  the rest of us  from a lot of tedious  "grunt work" in
  1019.           our programming.
  1020.                TechnoJock's Turbo Toolkit is a well done series of 12 Turbo
  1021.           Pascal  units  that  is worthy  of  your  consideration.   It  is
  1022.           published by TechnoJock Software, Inc. of Houston, Texas.
  1023.                Briefly,  the 12  units  are as  follows:   1)  fast  screen
  1024.           updating,  2) windows  and  boxes,  3)  user input  training,  4)
  1025.           directory  display and  retrieval, 5)  keyboard  manipulation and
  1026.           reading,  6) dynamic list management (this one is a real winner),
  1027.           7) menu display,  8) nested  menuing, 9)  pull down  (Lotus-like)
  1028.           menuing,  10) data type reading (like  reading only integers from
  1029.           the keyboard), 11) string manipulating (some good functions found
  1030.           here),  and 12) things that don't fit  anywhere else such as date
  1031.           manipulating, file information, on-screen clock and some printer
  1032.           testers.
  1033.                You'll find  some razzle-dazzle procedures in  this toolkit,
  1034.           such as sliding part of a screen in from the left or windows that
  1035.           appear to explode from the center.
  1036.                What  I appreciate about this toolkit is its overall concern
  1037.           with what the  screen looks like.  We are all  aware that some of
  1038.           the best  programs never get used because the screen is sloppy or
  1039.           un-inviting to the user.  The programmer who uses this toolkit is
  1040.           constantly encouraged to make a nice looking screen.
  1041.                Definitely  "home-brewed",  these units  bear  the stamp  of
  1042.           experience:  one  programmer knowing  what another  programmer is
  1043.           likely to need.  This shows  itself in the intuitive names  given
  1044.           to  procedures and functions.  A procedure named "TempMessageBox"
  1045.           is fairly self-explanatory as to what it is likely to do.
  1046.                The Toolkit sells for $49.95  and includes full source  code
  1047.           to  all the units, a printed manual  and a diskette full of short
  1048.           demo programs showing how to use each of the units.
  1049.                I have, on several  occasions, written to Bob  Ainsbury, the
  1050.           so-called "janitor" of TechnoJock  Software, Inc., with questions
  1051.           or problems  about the  units.   In  EVERY CASE  I have  received
  1052.           either a personal letter explaining how to modify the source code
  1053.           to do what I want, or, a diskette with a fixed bug.  This support
  1054.           alone is well worth the price of registration. In addition, there
  1055.                                                                          28
  1056.           are  no royalty payments for using his units in compiled programs
  1057.           you  distribute  and  he  gives  his customers  price  breaks  on
  1058.           upgrades, etc.
  1059.                Are  there any minuses?  Yes, I've found two things that may
  1060.           stand  in  your  way  when  using this  toolkit.    One,  a minor
  1061.           complaint, is  that the manual  could be  cleaned up.   There are
  1062.           several  inconsistent references  to procedure  calls and  places
  1063.           where  some information is missing.  These errors are not serious
  1064.           enough to  prohibit your effectively  using the manual,  but they
  1065.           may  slow  you  down  at  times.    A  second  and  more  serious
  1066.           consideration is getting used  to how one uses all  the functions
  1067.           and  procedures in the toolkit.  Fortunately, the disk comes with
  1068.           an  ample supply of  programs which demo  how to  use the various
  1069.           units.   But be  prepared  to spend  some time  looking at  these
  1070.           programs  and  studying  the code  in  them.    Doing so  at  the
  1071.           beginning will save  frustration later.   You probably won't  hit
  1072.           the ground running with this toolkit.
  1073.                Beginner  and advanced  programmers  who are  looking for  a
  1074.           workhorse toolbox that  can do a lot and get  the job done should
  1075.           consider TechnoJock's Turbo Toolkit.
  1076.                                                                          29
  1077.                         Turbo Pascal - The Complete Reference
  1078.                       
  1079.                                        A Review
  1080.                                     By Pete Davis
  1081.                I picked this book as my first to review because I feel that
  1082.           this book is invaluable for any Turbo Pascal Programmer. The book
  1083.           would be useful for  everyone from beginner to the  veteran Turbo
  1084.           Pascal Programmer.  Stephen K.  O'Brien, the Author  is obviously
  1085.           very  comfortable with  Turbo  Pascal and  his  book is  official
  1086.           enough to have been published by Borland-Osbourne/McGraw-Hill. 
  1087.                My  copy is  actually  for Version  4 but  it  has been  re-
  1088.           released for Version 5.5 of Turbo Pascal, which for the most part
  1089.           is almost identical in  content with the addition of  coverage of
  1090.           some 5.5 features.
  1091.                The first seven chapters are devoted mostly to the beginner,
  1092.           covering  everything  from  basic  data  structures   to  program
  1093.           structure  to the  Turbo Pascal  environment. Chapter  eight then
  1094.           begins on more complex ideas like pointers and dynamic memory.
  1095.                The  explanations of ideas are  very clear and  to the point
  1096.           and the most useful feature is the volume of examples included in
  1097.           the text. Almost every idea covered includes examples which drive
  1098.           home the point of every section.
  1099.                My personal favorite is chapter eighteen : 'Optimizing Turbo
  1100.           Pascal Programs', in which the author provides incredible insight
  1101.           into how to  make you programs  run faster  and use less  memory.
  1102.           This  chapter alone nearly pays for the book, especially when you
  1103.           are involved in large projects where speed and code size are very
  1104.           important.
  1105.                Another nice feature is the Procedure and Function reference
  1106.           near the end  of the book. This and other  reference areas in the
  1107.           book  make the  Turbo Pascal  Reference Guide,  which comes  with
  1108.           Turbo Pascal, almost worthless. (I shouldn't  really say that, as
  1109.           the  reference  guide  is quite  useful,  but  many  of the  more
  1110.           important aspects are covered in The Complete Reference). 
  1111.                I give Stephen K.  O'Brien five stars for a  fantastic book.
  1112.           If you have been using Turbo  Pascal for a long time, or you  are
  1113.           just learning to use it, I suggest that  you grab a copy and read
  1114.           through it.  It is by  far the most  useful book on  Turbo Pascal
  1115.           that I have ever seen.
  1116.                                                    _Pete Davis
  1117.                                                     Editor
  1118.                                                                          30
  1119.                                       Conclusion
  1120.                Well,  I would  first like  to thank  everyone for  being so
  1121.           patient in waiting  for the release  of this issue of  the Pascal
  1122.           NewsLetter.  I apologize for the  delay, but there  were a lot of
  1123.           things that held this issue up. Some of them, many of you already
  1124.           know about. Between my vacation and some computer problems, there
  1125.           was about a two week delay.
  1126.                When  I was  just getting  ready to  start finishing  up the
  1127.           issue, I got a the Profiler article and program which  I just had
  1128.           to include in this issue. I  think you'll agree that it was worth
  1129.           the  wait. Getting the article translated to English was the last
  1130.           thing holding this issue up, but it was worth the wait for me. 
  1131.                I would  like  to thank  everyone  who contributed  to  this
  1132.           issue, in particular,  I would like to  thank Bob Gowans  for his
  1133.           continued support and work  in the For Beginners column.  I would
  1134.           like to  thank Jan-Erik Rosinowski  for a fantastic  program. His
  1135.           contributions  are  welcome here  anytime. I  would also  like to
  1136.           thank Howard Sanner  for putting in a lot  of time in translating
  1137.           the article for me. I couldn't have done it without him.
  1138.                I have a few surprises that I hope I can spring in  the next
  1139.           issue,  but I  can't be  sure of  whether or  not things  will go
  1140.           through by then. If not, I still plan on having a good issue out.
  1141.           Please  send  in  your  contributions. They're  what  keeps  this
  1142.           newsletter coming out.  Even if you don't write well, send in the
  1143.           best you  can do, and  if you're  uncomfortable with it,  I'll be
  1144.           happy to go through and edit it.
  1145.                Also,  please keep  the  comments  and  suggestions  coming.
  1146.           They're a great help.
  1147.                Until the next issue, happy computing.
  1148.                                                    _Pete Davis
  1149.            
  1150.                                                                          31
  1151.                The  Pascal  NewsLetter  is  Copyrighted  by    Pete  Davis.
  1152.           Articles  submitted by others are the property of the authors and
  1153.           are  used with  permission. They  may  not be  treated separately
  1154.           from  this newsletter  without the  author's permission  and thus
  1155.           maintain  all distribution rules of the newsletter as a whole. It
  1156.           may be  freely  distributed in  un-modified form,  but no  charge
  1157.           whatsoever may be incurred on the recipient. All code is provided
  1158.           'as-is' with no guarantees whatsoever.
  1159.                The  Pascal NewsLetter  can be  obtained from  the following
  1160.           locations:
  1161.                          GEnie : General Electric Network for Information  
  1162.                                  Exchange. It is located in the IBMPC 
  1163.                                  filelist.
  1164.                         Simtel : Internet address: 26.2.0.74 or            
  1165.                                  Simtel20.ARPA It is located in the        
  1166.                                  <MSDOS.PASCAL> directory.
  1167.             Programmer's Forum : This is the home of the PNL.              
  1168.                                  Each issue can be found in                
  1169.                                  the MAG directory from the main area.
  1170.                                  The number is on the title page.
  1171.                If   you  would like   to   receive  back   issues  of   PNL
  1172.           directly  from  me,  send  a  diskette  and  $2.00  for shipping.
  1173.           Don't forget to include your address.
  1174.                          Send your order to:
  1175.                             Peter Davis
  1176.                             4851 Brandywine St. NW
  1177.                             Washington, DC   20016
  1178.                If you  are   a SysOp that   will regularly  carry PNL   and
  1179.           would like to   have your  bulletin board listed  as such,  here,
  1180.           send  me  a message  either  by  postal mail  or  at  one of  the
  1181.           electronic  addresses  given   on  the  title    page, with  your
  1182.           bulletin board's name, phone number, and your name.
  1183.                                                                          32
  1184.                                   Distribution List
  1185.                The following  is the phone numbers to bulletin boards known
  1186.           to carry  PNL. If you would  like your bulletin board's  name and
  1187.           number added  to  or deleted  from this  list, please  send me  a
  1188.           message at one of my many addresses. I can not guarantee whether 
  1189.           a listed board will have any particular issue, however.
  1190.              The Programmer's Forum ................. Phone: (202) 966-3647
  1191.              The Programmer's Forum is the home of the PNL.
  1192.              The Bored .............................. Phone: (512) 303-0471
  1193.              Classic City ........................... Phone: (404) 548-0726
  1194.              Theive's World ......................... Phone: (713) 463-8053
  1195.              Hippocampus ............................ Phone: (203) 484-4621
  1196.              Rogers State College BBS ............... Phone: (918) 341-8982
  1197.              The Foxtrot BBS ........................ Phone: (914) 567-1814
  1198.              Turbo City BBS ......................... Phone: (209) 599-7435
  1199.              Austin IEMUG/MIDI BBS .................. Phone: (512) 528-0626
  1200.              Laser Publishers ....................... Phone: (918) 438-2749
  1201.              Fargo RBBS-PC .......................... Phone: (701) 293-5973
  1202.              Momentary Lapse of Reason .............. Phone: (704) 327-6361
  1203.              The Demon's Den ........................ Phone: (508) 433-2702
  1204.              The Cannibal Cafe ...................... Phone: (508) 840-6589
  1205.              IBM Tech FIDO .......................... Phone: (508) 433-6491
  1206.              The User Friendly BBS .................. Phone: (704) 323-8223
  1207.              The Disseminator BBS (Australia)........ Phone: 61-7-368-1239
  1208.              Beyound Frontiers BBS (Denmark)......... Phone: (+45)8694-1609
  1209.              Collision Theory ....................... Phone: (703) 503-9441
  1210.              Ed-Net 9600 ............................ Phone: (604) 732-8877
  1211.